package cn.ecnu.controller;


import cn.ecnu.constant.ResponseStatus;
import cn.ecnu.entity.User;
import cn.ecnu.mapper.UserMapper;
import cn.ecnu.service.LoginService;
import cn.ecnu.service.RegisterService;
import cn.ecnu.service.UserInfoService;
import cn.ecnu.utils.R;
import cn.ecnu.vo.RegisterVo;
import cn.ecnu.vo.ResetVo;
import cn.ecnu.vo.UserCodeVo;
import cn.ecnu.vo.UserVo;
import org.apache.commons.codec.binary.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class LoginController {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginService loginService;

    @Autowired
    private RegisterService registerService;

    @Autowired
    private UserInfoService infoService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    static String SMS_PREFIX = "thirdparty:sms:";


    @PostMapping("/update/password")
    public R updateUserPassword(@RequestBody  UserVo userVo) {
        userMapper.updateUserPasswordById(userVo.getField(), userVo.getPassword());
        return R.ok();
    }

    @GetMapping("/list")
    public R getUserList() {
        List<User> list = infoService.getUserList();
        return R.ok().put("data", list);
    }


    @PostMapping("/loginWithPassword")
    public R loginWithPassword(@RequestBody UserVo userVo) {
        User user = loginService.getUserByNameOrPhone(userVo);
        if (user != null && user.getPassword().equals(userVo.getPassword())) {
            Map<String, Object> map = getVoMap(user);
            return R.ok().put("data", map);
        }
        return R.error(ResponseStatus.LOGIN_ERROR, "用户不存在或密码不正确");
    }

    @PostMapping("/loginWithCode")
    public R loginWithCode(@RequestBody UserCodeVo userVo) {
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String code = ops.get(SMS_PREFIX + userVo.getPhone());
        // 如果验证码不正确
        if (!StringUtils.equals(userVo.getCode(), code)) return R.error(ResponseStatus.CODE_ERROR, "验证码错误");

        // 验证码正确, 查找用户
        redisTemplate.delete(SMS_PREFIX + userVo.getPhone()); // 删除键
        User user = loginService.getUserByPhone(userVo.getPhone());
        if (user == null) return R.error(ResponseStatus.LOGIN_ERROR, "用户不存在");
        Map<String, Object> map = getVoMap(user);
        return R.ok().put("data", map);

    }

    public Map<String, Object> getVoMap(User user) {
        Map<String, Object> map = new HashMap<>();
        map.put("uid", user.getId());
        map.put("role", user.getRole());
        map.put("username", user.getUsername());
        map.put("phone", user.getPhone());
        return map;
    }

    @PostMapping("/register")
    public R register(@RequestBody RegisterVo registerVo) {
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String code = ops.get(SMS_PREFIX + registerVo.getPhone());
        // 如果验证码不正确
        if (!StringUtils.equals(registerVo.getCode(), code)) return R.error(ResponseStatus.CODE_ERROR, "验证码错误");

        // 检查注册的用户是否存在
        if (registerService.countUserByPhone(registerVo.getPhone()) > 0 ||
                registerService.countUserByName(registerVo.getUsername()) > 0) {
            return R.error(ResponseStatus.REGISTER_ERROR, "用户名或者手机号已存在");
        }

        redisTemplate.delete(SMS_PREFIX + registerVo.getPhone()); // 删除键

        // 创建一个新用户进行插入操作
        User user = new User();
        user.setId(ResponseStatus.uuidGenerator());
        user.setRole(0);
        BeanUtils.copyProperties(registerVo, user);
        System.out.println(user);
        registerService.insertUser(user);
        Map<String, Object> map = getVoMap(user);
        return R.ok().put("data", map);
    }

    @PostMapping("/reset")
    public R reset(@RequestBody ResetVo resetVo) {

        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String code = ops.get(SMS_PREFIX + resetVo.getPhone());
        // 如果验证码不正确
        if (!StringUtils.equals(resetVo.getCode(), code)) return R.error(ResponseStatus.CODE_ERROR, "验证码错误");
        redisTemplate.delete(SMS_PREFIX + resetVo.getPhone()); // 删除键
        infoService.updateUser(resetVo);
        return R.ok();
    }

}
